package com.fengxu.springcloud.service;

import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class PaymentService {

    // 表示一个可以正常执行的方法
    public String payment_ok(Long id){
        return "线程池 --> payment_ok " + Thread.currentThread().getName() + "ok id -> " + id;
    }

    // 表示一个产生超时的错误方法
    // fallbackMethod -> 服务降级后调用的方法!
    // commandProperties -> 配置服务降级的条件,可以配置的属性都在HystrixCommandProperties类中可以找得到
    @HystrixCommand(fallbackMethod = "payment_timeout_fallback", commandProperties = {
            // 该项表示设置服务的峰值时间3s
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String payment_timeout(){
        // 发生超时或者异常都出进行服务降级
//        int a = 1 / 0;
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池 --> payment_timeout " + Thread.currentThread().getName() + "ok";
    }
    // 该方法是payment_timeout服务降级之后的方法
    public String payment_timeout_fallback(){
        return "尊敬的用户您的访问超时，请稍后再试! --> payment_timeout_handler";
    }

    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            // 总意思为:在配置的时间敞口范围内,若服务满足调用次数>10(配置的)且失败率达到60%(配置的)的时候回开启断路器,并在10s（配置的）后尝试恢复
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 开启短路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 当在配置时间窗口内达到此数量的失败后，进行短路。默认20个
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 短路多久后开始尝试恢复
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") // 出错百分比阈值，当达到此阈值后，开始短路。默认50%
    })
    public String paymentCircuitBreaker(Long id){
        if(id < 0){
            throw new RuntimeException("*******id 不能为负数! ****");
        }
        return "paymentCircuitBreaker 调用成功! 流水号:" + IdUtil.simpleUUID();
    }
    // paymentCircuitBreaker降级后的服务
    public String paymentCircuitBreaker_fallback(Long id){
        return "id -> " + id + " 不能为负数!";
    }
}
